package com.example.aiinterview.service.impl;

import com.example.aiinterview.model.Interview;
import com.example.aiinterview.model.InterviewQuestion;
import com.example.aiinterview.model.User;
import com.example.aiinterview.repository.InterviewQuestionRepository;
import com.example.aiinterview.repository.InterviewRepository;
import com.example.aiinterview.service.AIService;
import com.example.aiinterview.service.InterviewService;
import lombok.RequiredArgsConstructor;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
@RequiredArgsConstructor
public class InterviewServiceImpl implements InterviewService {
    private static final Logger logger = LoggerFactory.getLogger(InterviewServiceImpl.class);

    private final InterviewRepository interviewRepository;
    private final InterviewQuestionRepository questionRepository;
    private final AIService aiService;

    @Override
    public String extractTextFromFile(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            throw new IOException("Invalid file name");
        }

        try (InputStream inputStream = file.getInputStream()) {
            if (fileName.endsWith(".pdf")) {
                return extractTextFromPdf(inputStream);
            } else if (fileName.endsWith(".docx")) {
                return extractTextFromDocx(inputStream);
            } else {
                throw new IOException("Unsupported file format. Please upload PDF or DOCX.");
            }
        }
    }

    private String extractTextFromPdf(InputStream inputStream) throws IOException {
        try (PDDocument document = PDDocument.load(inputStream)) {
            PDFTextStripper stripper = new PDFTextStripper();
            return stripper.getText(document);
        }
    }

    private String extractTextFromDocx(InputStream inputStream) throws IOException {
        try (XWPFDocument document = new XWPFDocument(inputStream)) {
            StringBuilder text = new StringBuilder();
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                text.append(paragraph.getText()).append("\n");
            }
            return text.toString();
        }
    }

    @Override
    @Transactional
    public Interview createNewInterview(User user, String resumeContent, String jobPosition) {
        logger.info("Creating new interview for user: {}", user.getUsername());
        try {
            Interview interview = new Interview();
            interview.setUser(user);
            interview.setResumeContent(resumeContent);
            interview.setJobPosition(jobPosition);
            interview.setStartTime(LocalDateTime.now());
            
            // 生成简历概括
            String resumeSummary = generateResumeSummary(resumeContent, jobPosition);
            interview.setResumeSummary(resumeSummary);
            
            return interviewRepository.save(interview);
        } catch (Exception e) {
            logger.error("Error creating interview for user: {}", user.getUsername(), e);
            throw e;
        }
    }


    @Override
    @Transactional
    public List<String> generateInterviewQuestions(Interview interview, int questionCount) {
        String prompt = createQuestionGenerationPrompt(interview, questionCount);
        List<String> questions = aiService.generateInterviewQuestions(prompt);

        // 处理AI返回空结果的情况
        if (questions == null || questions.isEmpty()) {
            questions = new ArrayList<>();
            questions.add("请介绍一下您与" + interview.getJobPosition() + "相关的经验");
            questions.add("您为什么对这个职位感兴趣？");
        }

        for (int i = 0; i < questions.size(); i++) {
            InterviewQuestion question = new InterviewQuestion();
            question.setInterview(interview);
            question.setQuestion(questions.get(i));
            question.setQuestionNumber(i + 1);
            interview.addQuestion(question);
        }

        interviewRepository.save(interview);
        return questions;
    }


    private String createQuestionGenerationPrompt(Interview interview, int questionCount) {
        return String.format("""
            你是一名专业的面试官，请根据以下简历内容和职位要求，生成%d个高质量的面试问题。
            
            职位：%s
            简历内容：
            %s
            
            请生成的问题应该：
            1. 与职位要求高度相关
            2. 能够评估候选人的专业技能和经验
            3. 包含技术问题、行为问题和情景问题
            4. 问题难度递进，从基础到深入
            
            请直接返回问题，每行一个问题，不要编号或其他说明文字。
            """, questionCount, interview.getJobPosition(), interview.getResumeContent());
    }

    @Override
    @Transactional
    public void saveUserAnswer(Interview interview, int questionNumber, String answer) {
        for (InterviewQuestion question : interview.getQuestions()) {
            if (question.getQuestionNumber() == questionNumber) {
                question.setUserAnswer(answer);
                questionRepository.save(question);
                break;
            }
        }
    }

    @Override
    @Transactional
    public void evaluateAnswersAndFinalize(Interview interview) {
        // Evaluate each answer
        double totalScore = 0;
        List<String> evaluationPrompts = new ArrayList<>();

        for (InterviewQuestion question : interview.getQuestions()) {
            String prompt = createAnswerEvaluationPrompt(question);
            String evaluation = aiService.evaluateAnswer(prompt);

            // Parse evaluation to get score and feedback
            // This is a simplified approach - you might want to improve this parsing
            double score = extractScoreFromEvaluation(evaluation);
            String feedback = extractFeedbackFromEvaluation(evaluation);

            question.setScore(score);
            question.setAiFeedback(feedback);
            questionRepository.save(question);

            totalScore += score;
            evaluationPrompts.add(String.format(
                    "Question: %s\nAnswer: %s\nScore: %.1f/10\nFeedback: %s",
                    question.getQuestion(), question.getUserAnswer(), score, feedback
            ));
        }

        // Calculate final score
        double finalScore = totalScore / interview.getQuestions().size();
        interview.setFinalScore(finalScore);

        // Generate overall feedback
        String finalFeedbackPrompt = createFinalFeedbackPrompt(interview, evaluationPrompts);
        String finalFeedback = aiService.generateFinalFeedback(finalFeedbackPrompt);


        if (finalFeedback == null || finalFeedback.trim().isEmpty() || finalFeedback.contains("错误")) {
            StringBuilder fallback = new StringBuilder();
            fallback.append("综合评价：");
            if (finalScore >= 8) {
                fallback.append("表现优秀，具备较强的岗位匹配度和实战能力。\n\n");
            } else if (finalScore >= 6) {
                fallback.append("整体表现良好，基本满足岗位需求，仍有进一步提升空间。\n\n");
            } else if (finalScore >= 4) {
                fallback.append("基础能力尚可，但与岗位要求仍存在一定差距。建议加强核心技能训练。\n\n");
            } else {
                fallback.append("当前与岗位要求匹配度较弱，建议系统性提升专业技能与项目经验。\n\n");
            }

            // 汇总优势与改进建议（基于得分高低的启发式描述）
            fallback.append("主要优势：\n");
            fallback.append("1. 回答条理清晰，表达较为流畅。\n");
            fallback.append("2. 具备与岗位相关的基础知识储备。\n");
            fallback.append("3. 学习与适应能力较强。\n\n");

            fallback.append("需要改进：\n");
            if (finalScore < 7) {
                fallback.append("1. 进一步夯实核心技术栈，补齐关键知识点。\n");
            } else {
                fallback.append("1. 深入打磨高级能力与架构思维。\n");
            }
            fallback.append("2. 增强结合项目的案例说明与数据支撑。\n");
            fallback.append("3. 提升问题拆解与场景化思考能力。\n\n");

            fallback.append("建议：根据岗位（").append(interview.getJobPosition()).append("）要求，制定阶段性学习与实战计划，持续输出作品与总结，并在后续面试中突出与岗位最匹配的经验亮点。");

            finalFeedback = fallback.toString();
        }

        interview.setFeedback(finalFeedback);

        interview.setEndTime(LocalDateTime.now());
        interviewRepository.save(interview);
    }

    private String createAnswerEvaluationPrompt(InterviewQuestion question) {
        return String.format("""
            请对以下面试回答进行专业评估。
            
            问题：%s
            回答：%s
            
            请从以下维度进行评估：
            1. 回答的完整性和准确性（0-10分）
            2. 专业知识和技能展示（0-10分）
            3. 逻辑思维和表达能力（0-10分）
            4. 实际经验和案例说明（0-10分）
            
            请按以下格式返回：
            总分：X/10
            详细评估：[具体的评估意见和改进建议]
            """, question.getQuestion(), question.getUserAnswer());
    }

    private double extractScoreFromEvaluation(String evaluation) {
        // 更稳健的分数解析：支持 “总分：X/10”、“Score: X/10”、“X/10”、“X” 等格式
        if (evaluation == null) {
            return 5.0;
        }

        String text = evaluation.replace(" ", "");

        // 1) 匹配形如 总分：X/10 或 Score:X/10 或 任意包含 X/10 的片段
        java.util.regex.Matcher m = java.util.regex.Pattern
                .compile("([0-9]+(?:\\.[0-9]+)?)[/]10")
                .matcher(text);
        if (m.find()) {
            try {
                return Double.parseDouble(m.group(1));
            } catch (NumberFormatException ignored) {}
        }

        // 2) 匹配形如 总分：X 或行首纯数字
        m = java.util.regex.Pattern.compile("总分[:：]?([0-9]+(?:\\.[0-9]+)?)").matcher(text);
        if (m.find()) {
            try {
                return Double.parseDouble(m.group(1));
            } catch (NumberFormatException ignored) {}
        }

        String[] lines = evaluation.split("\n");
        for (String line : lines) {
            String trimmed = line.trim();
            try {
                return Double.parseDouble(trimmed);
            } catch (NumberFormatException ignored) {
                // try next line
            }
        }
        return 6.0; // 解析失败给一个中位默认值，避免偏低
    }

    private String extractFeedbackFromEvaluation(String evaluation) {
        // Simplified feedback extraction
        String[] lines = evaluation.split("\n");
        StringBuilder feedback = new StringBuilder();
        boolean foundScore = false;

        for (String line : lines) {
            try {
                Double.parseDouble(line.trim());
                foundScore = true;
            } catch (NumberFormatException e) {
                if (foundScore) {
                    feedback.append(line).append("\n");
                }
            }
        }

        return feedback.toString().trim();
    }

    private String createFinalFeedbackPrompt(Interview interview, List<String> evaluationPrompts) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("请基于以下面试评估结果，为候选人提供全面的面试总结报告。\n\n");
        prompt.append("职位：").append(interview.getJobPosition()).append("\n");
        prompt.append("候选人简历概括：").append(interview.getResumeSummary()).append("\n\n");
        prompt.append("各问题评估详情：\n");
        
        for (String eval : evaluationPrompts) {
            prompt.append(eval).append("\n\n");
        }
        
        prompt.append("请提供以下内容的综合评估报告：\n");
        prompt.append("1. 总体评分（1-10分）\n");
        prompt.append("2. 主要优势（至少3点）\n");
        prompt.append("3. 需要改进的地方（至少3点）\n");
        prompt.append("4. 是否推荐录用及理由\n");
        prompt.append("5. 具体的职业发展建议\n");

        return prompt.toString();
    }

    @Override
    public Interview findById(Long id) {
        return interviewRepository.findById(id).orElse(null);
    }

    @Override
    public List<Interview> findByUser(User user) {
        return interviewRepository.findByUserOrderByStartTimeDesc(user);
    }

    @Override
    @Transactional
    public Interview saveInterview(Interview interview) {
        return interviewRepository.save(interview);
    }

    @Override
    public String generateResumeSummary(String resumeContent, String jobPosition) {
        try {
            String prompt = String.format("""
                你是一名专业的HR，请分析以下简历内容，并针对职位"%s"生成一个简洁的简历概括。
                
                分析要求：
                1. 提取候选人的核心技能和经验
                2. 识别与目标职位匹配的优势
                3. 总结教育背景和工作经历要点
                4. 评估候选人的整体竞争力
                
                简历内容：
                %s
                
                请用中文回答，格式如下：
                【核心技能】：列出主要技能
                【工作经验】：总结相关经验
                【教育背景】：简要说明
                【匹配度】：与目标职位的匹配程度
                
                控制在300字以内。
                """, jobPosition, resumeContent);
            
            String summary = aiService.generateResponse(prompt);
            if (summary == null || summary.trim().isEmpty()) {
                return "候选人简历内容丰富，具备相关工作经验，适合该职位要求。";
            }
            return summary;
        } catch (Exception e) {
            logger.error("Error generating resume summary", e);
            return "候选人简历内容丰富，具备相关工作经验，适合该职位要求。";
        }
    }

    @Override
    public String generateFirstQuestion(String prompt) {
        if (prompt == null || prompt.trim().isEmpty()) {
            logger.warn("Empty prompt provided for first question generation");
            return "请介绍一下您与应聘职位相关的经验";
        }

        int maxRetries = 2;
        long[] retryDelays = {1000, 2000}; // 重试延迟时间（毫秒）

        for (int attempt = 0; attempt <= maxRetries; attempt++) {
            try {
                logger.info("Generating first question, attempt: {}", attempt + 1);
                String result = aiService.generateResponse(prompt);

                // 验证结果
                if (result != null && !result.trim().isEmpty() && !result.contains("错误")) {
                    String trimmedResult = result.trim();
                    logger.info("Successfully generated first question: {}", trimmedResult);
                    return trimmedResult;
                }

                logger.warn("AI service returned invalid response: {}", result);

                // 如果不是最后一次尝试，等待后重试
                if (attempt < maxRetries && retryDelays[attempt] > 0) {
                    Thread.sleep(retryDelays[attempt]);
                }
            } catch (InterruptedException e) {
                logger.warn("First question generation interrupted", e);
                Thread.currentThread().interrupt();
                break;
            } catch (Exception e) {
                logger.error("Error generating first question, attempt: {}", attempt + 1, e);

                // 如果不是最后一次尝试，等待后重试
                if (attempt < maxRetries && attempt < retryDelays.length) {
                    try {
                        Thread.sleep(retryDelays[attempt]);
                    } catch (InterruptedException ie) {
                        logger.warn("Retry delay interrupted", ie);
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }

        logger.warn("All attempts to generate first question failed, returning default question");
        return "请介绍一下您与应聘职位相关的经验";
    }

}
